package com.pangu.util;

import java.io.File;

import android.os.Environment;
import android.os.StatFs;

import com.pangu.AMApplication;
import com.pangu.util.StringUtil;

/**
 * 文件工具类
 * <p/>
 * Created by cxlin
 */
public class FileUtil {

	// 最小的剩余空间 （字节） 10m
	public static final long MIN_BS_STORE_SPACE = 1024 * 1024 * 10;

	// 访问权限 7:U,5:G,5:O
	private static final String CMD_MOD_PRI_755 = "755";

	// SD卡写测试间隔
	public static final long SDCARD_WRITE_TEST_INTERVEL = 10000L;
	// SD卡写测试文件名
	public static final String SDcardTestWriteFileName = "testFile";
	// SD卡写测试是否可写
	private static boolean isSDcardCanWrite = false;
	// SD卡写测试最近一次测试时间
	private static long lastSDcardTestWriteTime = 0L;

	/**
	 * 获得存储目录 <br>
	 * 
	 * @return
	 */
	public static String getStoreDir() {
		// 确定本机环境是否可以进行下载
		String savePath = getSdcardStoreDir();
		if (savePath == null) {
			// 无SD卡，则去内部存储路径
			savePath = getPrivateStoreDir();
		}
		return savePath;
	}

	/**
	 * 获得sdcard存储目录<br>
	 */
	public static String getSdcardStoreDir() {
		String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state)) {
			// 确定本机环境是否可以读写
			File file = Environment.getExternalStorageDirectory();
			if (file.exists()) {
				File storeFile = new File(file.getAbsolutePath());
				if (!storeFile.exists()) {
					boolean canWrite = storeFile.mkdirs();
					if (!canWrite) {
						return null;
					}
				}
				return storeFile.getAbsolutePath();

			} else {
				return null;
			}

		} else {
			return null;
		}
	}

	/**
	 * 获得私有存储目录<br>
	 * 私有根目录 /data/data/com.zz.zz/
	 * 
	 * @return
	 */
	public static String getPrivateStoreDir() {
		File file = AMApplication.getInstance().getFilesDir();
		if (file.exists()) {
			return file.getParent();

		} else {
			return null;
		}
	}

	/**
	 * 获取私有的数据库存储目录（/data/data/com.zz.zz/databases）
	 * 
	 * @return
	 */
	public static String getPrivateDatabaseStoreDir() {
		String parentDir = getPrivateStoreDir();
		if (parentDir == null) {
			return null;

		} else {
			StringBuilder sb = new StringBuilder(parentDir);
			sb.append(File.separator);
			sb.append("databases");
			return sb.toString();
		}
	}

	/**
	 * 是否是私有路径
	 * 
	 * @param path
	 */
	public static boolean isPrivateStoreDir(String path) {
		String priPath = getPrivateStoreDir();
		if (path != null && priPath != null && path.startsWith(priPath)) {
			return true;

		} else {
			return false;
		}
	}

	/**
	 * 修改当前文件或目录自身及其父节点直至rootPath的权限
	 * 
	 * @param path
	 * @param rootPath
	 */
	public static void changeFileCurrentAndParentPri(String path, String rootPath) {
		changeFileCurrentAndParentPri(path, CMD_MOD_PRI_755, rootPath);

	}

	/**
	 * 修改当前文件或目录自身及其父节点直至rootPath的权限
	 * 
	 * @param path
	 * @param mod
	 * @param rootPath
	 */
	public static void changeFileCurrentAndParentPri(String path, String mod, String rootPath) {
		try {
			// 先修改自身权限
			changeFilePri(path, mod);

			File rootFile = null;
			if (rootPath != null && rootPath.trim().length() > 0) {
				rootFile = new File(rootPath);
			}

			// 遍历直接父节点
			File file = new File(path);
			file = file.getParentFile();
			while (file != null) {
				if (rootFile != null && !file.getAbsolutePath().contains(rootFile.getAbsolutePath())) {
					// 当前路径是不是指定的根路径或不在根路径下，直接退出
					break;
				}

				// 当前路径是指定的根路径或在根路径下
				changeFilePri(file.getAbsolutePath(), mod);
				file = file.getParentFile();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 修改当前文件或目录自身的权限
	 * 
	 * @param path
	 * @param mod
	 */
	public static void changeFilePri(String path, String mod) {
		try {
			// 用||号进行短路
			String cmd = "chmod " + mod + " " + path + " || busybox chmod " + mod + " " + path;
			Runtime.getRuntime().exec(cmd);

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 修改当前文件或目录自身的权限为默认值
	 * 
	 * @param path
	 */
	public static void changeFileDefaultPri(String path) {
		changeFilePri(path, CMD_MOD_PRI_755);

	}

	/**
	 * 检测当前下载位置是否空间足够，单位KB 测试大小要加上额外的10M
	 * 
	 * @param size
	 * @return
	 */
	public static boolean isCurrentStorageEnough(int size) {
		String savePath = getSdcardStoreDir();
		if (savePath == null) {
			savePath = getPrivateStoreDir();
		}

		return !isStorageSpaceFull(savePath, size * 1024L + MIN_BS_STORE_SPACE);
	}

	/**
	 * 存储空间是否不足指定大小
	 * 
	 * @param path
	 * @param size
	 *            字节
	 * @return
	 */
	public static boolean isStorageSpaceFull(String path, long size) {
		if (path != null) {
			StatFs sf = new StatFs(path);
			// 这里是字节
			long restSize = sf.getBlockSize() * (long) sf.getAvailableBlocks();
			return (restSize < size);

		} else {
			return false;
		}
	}

	/**
	 * 获得下载保存目录<br>
	 * 允许外部空间及私有空间。
	 * 
	 * @return
	 */
	public static String getDownloadDir(AMApplication imContext) {
		String downloadDir = imContext.getContextRootPathName() + File.separator + "download";
		String savePath = getStoreDir();
		if (savePath != null) {
			savePath += File.separator + downloadDir;

		} else {
			savePath = getPrivateStoreDir();
			if (savePath != null) {
				savePath += File.separator + downloadDir;
			}
		}

		// 检查目录是否存在
		if (savePath != null) {
			File file = new File(savePath);
			if (!file.exists()) {
				file.mkdirs();
				if (isPrivateStoreDir(savePath)) {
					// 权限路径改为hiapk_play这个根目录，other角色要确保有rx权限
					String privateRootDir = getPrivateStoreDir() + File.separator + imContext.getContextRootPathName();
					changeFileCurrentAndParentPri(savePath, privateRootDir);
				}
			}
		}

		return savePath;
	}

	/**
	 * 路径是否可写 当一个下载路径可写时，认为10秒内SD卡所有下载路径均可写
	 * 
	 * @return
	 */
	public static boolean isPathCanWrite(String path) {
		if (StringUtil.isEmptyString(path)) {
			return false;
		}

		// 10秒内，返回之前的数值
		if (System.currentTimeMillis() - lastSDcardTestWriteTime < SDCARD_WRITE_TEST_INTERVEL) {
			return isSDcardCanWrite;

		} else {
			lastSDcardTestWriteTime = System.currentTimeMillis();
		}

		File testFile = null;
		try {
			// 生成测试文件
			String testFileAbsName = null;
			if (path.endsWith(File.separator)) {
				testFileAbsName = path + SDcardTestWriteFileName;

			} else {
				int laseSeparator = path.lastIndexOf(File.separator);
				testFileAbsName = path.substring(0, laseSeparator);
				testFileAbsName = testFileAbsName + File.separator + SDcardTestWriteFileName;
			}

			// 测试文件可写
			testFile = new File(testFileAbsName);
			if (testFile.exists()) {
				isSDcardCanWrite = testFile.delete();

			} else {
				isSDcardCanWrite = testFile.createNewFile();
			}

		} catch (Exception e) {
			e.printStackTrace();
			isSDcardCanWrite = false;

		} finally {
			if (testFile != null && testFile.exists()) {
				testFile.delete();
			}
		}

		return isSDcardCanWrite;
	}

	public static void delAllChildrenFiles(String path) {
		try {
			File dir = new File(path);
			if (dir.exists()) {
				File[] delFile = dir.listFiles();
				if (delFile != null) {
					for (File file : delFile) {
						file.deleteOnExit();
					}
				}

			}
		} finally {
		}
	}

}
